<?php
	require_once 'dbConnection.php';
	require 'Slim/Slim.php';
	\Slim\Slim::registerAutoloader();

	define("SUCCESS", 0);
	define("CRITICAL", -1);
	define("DEFAULTERROR", 1);
	define("UNUSUAL", 2);

	$app = new \Slim\Slim();

	$app->get('/info', function() {
		echo getJsonData(array('version'=>1, 'description'=>"Asoko Official"));
	});

	$app->group('/login', function () use ($app) {
		$app->contentType('application/json; charset=utf-8');

		$app->get('/:email/:passwd', function($email, $passwd){
			$userid = getIdForCredentials($email, hash('sha512', $passwd));
			if($userid)
			{
				$session = getOrCreateSession($userid);
				echo getJsonData(array('session'=>$session));
			}
			else echo getJsonError("Invalid login credentials");
		});
	});

	$app->group('/user', function () use ($app) {
		$app->contentType('application/json; charset=utf-8');

		$app->get('/session/:session', function($session) {
			$id = getIdForSession($session);
			if($id) echo getJsonData($id);
			else echo getJsonError("No such session");
		});

		$app->get('/id/:id', function($id) {
			$user = getUserForId($id);
			if($user) echo getJsonData($user);
			else echo getJsonError("User not found");
		});

	});

	$app->group('/post', function () use ($app) {
		$app->contentType('application/json; charset=utf-8');

		$app->get('/id/:id', function($id) {
			$post = getPostForId($id);
			if($post) echo getJsonData($post);
			else echo getJsonError("Post not found");
		});

		$app->get('/userid/:id', function($id) {
			$posts = getPostsForUser($id);
			if($posts !== NULL) echo getJsonData($posts);
			else echo getJsonError("User not found");
		});

		$app->get('/coordinates/:latne/:lonne/:latsw/:lonsw', function($latne, $lonne, $latsw, $lonsw) {
			$posts = getPostsForCoordinates($latne, $lonne, $latsw, $lonsw);
			if($posts !== NULL) echo getJsonData($posts);
			else echo getJsonError("Shit happened", 2);

		});

		$app->post('/create', function() use ($app) {
			$response = createPostFromRequest($app->request());
			echo json_encode($response); //status is unknown
		});

		$app->put('/id/:id', function($id) use ($app) {
			$response = updatePostFromRequest($id, $app->request());
			echo json_encode($response); //status is unknown
		});

	});

	$app->group('/image', function () use ($app) {
		$app->contentType('application/json; charset=utf-8');

		$app->get('/id/:id', function($id) {
			$image = getImageDataForId($id);
			if($image) echo getJsonData(array('image'=>$image));
			else echo getJsonError("Image not found");
		});
	});

	$app->notFound(function () use ($app) {
		$app->halt(404, getJSONError("API Function not found", DEFAULTERROR));
	});

	$app->run();

	///////////////////////////////////////////////////////////////////



	function getJsonData($data)
        {
                $arr = array('return'=>SUCCESS, 'data'=>$data);
                return json_encode($arr);
        }

        function getJsonError($error, $retval=DEFAULTERROR)
        {
                $arr = array('return'=>$retval, 'error'=>$error);
                return json_encode($arr);
        }


	function getIdForCredentials($email, $hash) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT id from USER where email = :email and pwd = :pwd");
		$stmt->bindParam("email", $email);
		$stmt->bindParam("pwd", $hash);
		$stmt->execute();
		$user = $stmt->fetchColumn();
		if($user) return (int)$user;
		else return NULL;
	}

	function getOrCreateSession($userid) {
		$db = getConnection();
		$session = null;

		//Check if session exists
		$stmt = $db->prepare("SELECT id from SESSION where userid = :userid");
		$stmt->bindParam("userid", $userid);
		$stmt->execute();
		$session = $stmt->fetchColumn();
		if($session) return $session;

		//Create session
		$session = hash('sha512',mt_rand());
		$stmt = $db->prepare("INSERT INTO SESSION (id, userid) VALUES (:id, :userid)");
		$stmt->bindParam("userid", $userid);
		$stmt->bindParam("id", $session);
		$stmt->execute();
		return $session;

	}

	function getIdForSession($session) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT userid FROM SESSION WHERE id = :id");
		$stmt->bindParam("id", $session);
		$stmt->execute();
		$user = $stmt->fetchColumn();
		if($user) return (int)$user;
		else return NULL;
	}

	function getUserForId($id) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT name, email, register_date FROM USER where id = :id");
		$stmt->bindParam("id", $id);
		$stmt->execute();
		$user = $stmt->fetchObject();
		if($user) return $user;
		else return NULL;
	}

	function getPostForId($id) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT p.text, p.latitude, p.longitude, p.stamp, p.userid, u.name from POST p join USER u on p.userid = u.id where p.id=:id");
		$stmt->bindParam("id", $id);
		$stmt->execute();
		$post = $stmt->fetchObject();

		if($post) {
			$images = getImagesForPostId($id);
			if($images) {
				return array(
					'text'=>$post->text,
					'latitude'=>$post->latitude,
					'longitude'=>$post->longitude,
					'stamp'=>$post->stamp,
					'userid'=>$post->userid,
					'name'=>$post->name,
					'images'=>$images
				);

			}
			else return $post;
		}
		else return NULL;

	}

	function getImagesForPostId($id) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT id from IMAGE where postid=:id");
		$stmt->bindParam("id", $id);
		$stmt->execute();
		$images = array();
		while($imgid = $stmt->fetchColumn())
		{
			$images[] = (int)$imgid;
		}
		if($images) return $images;
		else return NULL;
	}

	function getPostsForUser($id) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT id from POST WHERE userid = :userid");
		$stmt->bindParam("userid", $id);
		$stmt->execute();
		$posts = array();
		while ($postid = $stmt->fetchColumn()) {
			$posts[] = (int)$postid;
		}
		$user = getUserForId($id);
		if ($posts || $user) return $posts;
		else return NULL;

	}

	function getPostsForCoordinates($latne, $lonne, $latsw, $lonsw) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT id as res FROM POST where latitude between :latsw AND :latne AND longitude between :lonsw and :lonne");
		$stmt->bindParam("latne", $latne);
		$stmt->bindParam("latsw", $latsw);
		$stmt->bindParam("lonne", $lonne);
		$stmt->bindParam("lonsw", $lonsw);
		$stmt->execute();
		$posts = array();
		while ($postid = $stmt->fetchColumn()) {
			$posts[] = (int)$postid;
		}
		return $posts;

	}

	function createPostFromRequest($request) {
    		$session = $request->post('session');
                $lat = $request->post('latitude');
                $lon = $request->post('longitude');
                $text = $request->post('text');
		$image = $request->post('image');
		$hasimage = ($image !== NULL);
		if($text === NULL) {
			return array('return'=>DEFAULTERROR, 'error'=>"Text cannot be empty");
		}
		$userid = getIdForSession($session);
		if($userid === NULL) {
			return array('return'=>DEFAULTERROR, 'error'=>"Invalid session");
		}

		$db = getConnection();
		$stmt = $db->prepare("INSERT INTO POST (latitude, longitude, text, userid) VALUES (:latitude, :longitude, :text, :userid)");
		$stmt->bindParam("latitude", $lat);
		$stmt->bindParam("longitude", $lon);
		$stmt->bindParam("text", $text);
		$stmt->bindParam("userid", $userid);
		$stmt->execute();
		$postid = $db->lastInsertId();

		if($hasimage) {
			$stmt = $db->prepare("INSERT INTO IMAGE(data, postid) VALUES (:data, :postid)");
			$stmt->bindParam("data", $image);
			$stmt->bindParam("postid", $postid);
			$stmt->execute();
		}

		return array('return'=>SUCCESS, 'data'=>array('uri'=>"/post/id/$postid"));


	}

	function updatePostFromRequest($postid, $request) {
		$session = $request->post('session');
                $text = $request->post('text');
		if($text === NULL) {
			return array('return'=>DEFAULTERROR, 'error'=>"Text cannot be empty");
		}

		$userid = getIdForSession($session);
		if($userid === NULL) {
			return array('return'=>DEFAULTERROR, 'error'=>"Invalid session");
		}

		$db = getConnection();
		$stmt = $db->prepare("UPDATE POST SET text = :text where id = :id AND userid = :userid");
		$stmt->bindParam("text", $text);
		$stmt->bindParam("id", $postid);
		$stmt->bindParam("userid", $userid);
		$stmt->execute();

		return array('return'=>SUCCESS, 'data'=>array('uri'=>"/post/id/$postid"));

	}

	function getImageDataForId($id) {
		$db = getConnection();
		$stmt = $db->prepare("SELECT data FROM IMAGE where id = :id");
		$stmt->bindParam("id", $id);
		$stmt->execute();
		$data = $stmt->fetchColumn();

		if($data) return $data;
		else return NULL;

	}

?>

